package com.rfid.rfidbluetooth.manager;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import com.rfid.base.util.ByteUtils;
import com.rfid.base.util.LogUtils;
import com.rfid.rfidbluetooth.CmdBuild;
import com.rfid.rfidbluetooth.InWriteableStream;
import com.rfid.rfidbluetooth.Rfid;
import com.rfid.rfidbluetooth.RfidListener;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public enum  BleClientManager implements BluetoothAdapter.LeScanCallback {

    INSTANCE;
    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    BluetoothManager.BluetoothListener mListener;
    RfidListener mRfidListener;
    BluetoothGatt mBluetoothGatt;

    BluetoothGattCharacteristic mWrite;

    boolean reading;

    Executor mExecutor = Executors.newSingleThreadExecutor();
    InWriteableStream mInputStream;

    public void connectBle(Context context, BluetoothDevice device) throws Exception {
        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (Exception e) {
            }
        }
        mInputStream = new InWriteableStream();
        mBluetoothGatt = device.connectGatt(context, false, new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                System.out.println("onConnectionStateChange newState = " + newState);
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    // 连接成功后发现服务
                    gatt.discoverServices();
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    // 处理断开连接的情况
                    System.out.println("STATE_DISCONNECTED");
                    if (mListener != null) {
                        mListener.onConnect(false);
                    }
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                System.out.println("onServicesDiscovered status = " + status);
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    List<BluetoothGattService> ss = gatt.getServices();
                    for (BluetoothGattService b : ss) {
                        System.out.println(b.getUuid());
                        System.out.println(uuid.equals(b.getUuid()));
                    }
                    System.out.println("begain get service");
                    BluetoothGattService service = gatt.getService(uuid);
                    System.out.println("get service");
                    for (BluetoothGattCharacteristic ch : service.getCharacteristics()) {
                        System.out.println(ch.getUuid() + "-------" + ch.getProperties());
                    }
                    BluetoothGattCharacteristic txCharacteristic = service.getCharacteristic(uuid);
                    System.out.println("get txCharacteristic > " + txCharacteristic);
                    BluetoothGattCharacteristic rxCharacteristic = service.getCharacteristic(uuid);
                    System.out.println("get rxCharacteristic " + rxCharacteristic);
                    mWrite = txCharacteristic;
                    // 写入数据
//                txCharacteristic.setValue("Hello, BLE!");
//                gatt.writeCharacteristic(txCharacteristic);
                    System.out.println("setCharacteristicNotification");
                    // 设置通知
                    gatt.setCharacteristicNotification(rxCharacteristic, true);
//                BluetoothGattDescriptor descriptor = rxCharacteristic.getDescriptor(uuid);
//                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
//                gatt.writeDescriptor(descriptor);;
                    System.out.println("onConnect");
                    startRead();
                    if (mListener != null) {
                        mListener.onConnect(true);
                    }
                }

            }

            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                byte[] value = characteristic.getValue();
                System.out.println("receive = " + ByteUtils.bytesToHexString(value));
                try {
                    mInputStream.writeBytes(value);
                    ToServerManager.INSTANCE.send(value);
                } catch (IOException e) {
                    e.printStackTrace();
                }
//                String msg = new String(value);
//                System.out.println("receive = " + msg);
//                if (mListener != null) {
//                    mListener.onMsg(msg);
//                }
            }

            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicWrite(gatt, characteristic, status);
                LogUtils.v("onCharacteristicWrite status = " + status);
            }

            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicRead(gatt, characteristic, status);
                System.out.println("onCharacteristicRead");
            }

            @Override
            public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
                super.onReliableWriteCompleted(gatt, status);
                System.out.println("onReliableWriteCompleted status = " + status);
            }
        });

    }

    private void startRead() {
        if (reading) {
            return;
        }
        reading = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                DataInputStream input = new DataInputStream(mInputStream);
                while (reading) {
                    try {
                        short cmd = input.readShort();
                        if (cmd == CmdBuild.CMD_REQ_RFID) {
                            System.out.println("CMD_REQ_RFID");
                            List<Rfid>rfids = CmdBuild.readRfids(input);
                            if (mRfidListener != null) {
                                mRfidListener.onRfids(rfids);
                            }
//                            ToServerManager.INSTANCE.send(rfids);
                        } else if (cmd == CmdBuild.CMD_M_EPC) {
                            boolean s = CmdBuild.readModifyEpcResualt(input);
                            if (mRfidListener != null) {
                                mRfidListener.onModifyEpcResult(s);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException interruptedException) {
                            interruptedException.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

    public void sendHello() {
        System.out.println("sendHello");
        mWrite.setValue("hello world");
        mBluetoothGatt.writeCharacteristic(mWrite);
    }

    public void modifyEpc(int ph,int port,String epc) {
        byte data[] = CmdBuild.modifyEpc(1,ph,port,epc);
        mWrite.setValue(data);
        mBluetoothGatt.writeCharacteristic(mWrite);
    }

    public boolean startScanBle() {
        System.out.println("startScanBle");
        android.bluetooth.BluetoothAdapter bluetoothAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            System.out.println("bluetoothAdapter not enable");
            return false;
        }
        bluetoothAdapter.startLeScan(this);
        return true;
    }

    public void stopScan() {
        android.bluetooth.BluetoothAdapter bluetoothAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
        bluetoothAdapter.stopLeScan(this);
    }


    public void setListener(BluetoothManager.BluetoothListener listener) {
        mListener = listener;
    }

    public void setRfidListener(RfidListener listener) {
        mRfidListener = listener;
    }

    public void reqRfids(int shelf,int pn) {
        byte req[] = CmdBuild.reqRfid(shelf,pn);
        mWrite.setValue(req);
        mBluetoothGatt.writeCharacteristic(mWrite);
    }


    public void closeBle() {
        reading = false;
        mBluetoothGatt.disconnect();
        mBluetoothGatt.close();
        try {
            mInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        if (mListener != null) {
            mListener.onDeviceFound(device);
        }
    }
}
